<!DOCTYPE html>
<html lang="utf-8">
<head>
    <meta charset="utf-8">
    <title>第一个vue应用</title>
    <script src="../js/vue.2.7.0.js"></script>
</head>
<body>
<div id="app">
    <p>{{ total }}</p>
    <button-counter v-on:increment="incermentTotal"></button-counter>
    <button-counter v-on:increment="incermentTotal"></button-counter>
</div>
<script>
    Vue.component('button-counter', {
        template: '<button @click="incrementHandler">{{ counter }}</button>',
        data: function () {
            return {counter: 0}

        },
        methods: {
            incrementHandler() {
                this.counter += 1
                this.$emit('increment')
            }
        }
    })
    new Vue({
        el: '#app',
        data: {
            total: 0
        },
        methods: {
            incermentTotal() {
                this.total += 1
            }
        }
    })
</script>

<!--
自定义组件的 v-model
组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件。
<input v-model="parentData">

等价于：
<input :value="parentData"  @input="parentData = $event.target.value" >
-->

<div id="pcsync">
    <change-input v-model="num"></change-input>
    <p>输入的数字为:{{ num }}</p>
</div>
<script>
    Vue.component('change-input', {
        template: `
          <p>
          <input ref="input" :value="value" @input="$emit('input',$event.target.value)">
          </p>
        `,
        props: ['value']
    })
    new Vue({
        el: '#pcsync',
        data: {
            num: 100
        }
    })
</script>

<div id="appCheck">
    <base-checkbox v-model="lovingVue"></base-checkbox>
    <div v-show="lovingVue">
        如果选择框打勾我就会显示。
    </div>
</div>
<script>
    // 注册
    Vue.component('base-checkbox', {

        model: {
            prop: 'checked',
            event: 'change'  // onchange 事件
        },
        props: {
            checked: Boolean
        },

        template: `
          <input
              type="checkbox"
              v-bind:checked="checked"
              v-on:change="$emit('change', $event.target.checked)"
          >
        `
    })
    // 创建根实例
    new Vue({
        el: '#appCheck',
        data: {
            lovingVue: true
        }
    })
</script>
<!--
    Vue.js 自定义指令
  除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。
  下面我们注册一个全局指令 v-focus, 该指令的功能是在页面加载时，元素获得焦点：
-->
<div id="appCommand">
    <p>页面载入时，input 元素自动获取焦点：</p>
    <input v-focus>
</div>
<div id="appCommand02">
    <p>02页面载入时，input 元素自动获取焦点：</p>
    <input v-focus>
</div>

<script>
    // 注册一个全局自定义指令 v-focus
    Vue.directive('focus', {
        // 当绑定元素插入到 DOM 中。
        inserted: function (el) {
            // 聚焦元素
            el.focus()
        }
    })
    // 创建根实例
    new Vue({
        el: '#appCommand'
    })

    // 我们也可以在实例使用 directives 选项来注册局部指令，这样指令只能在这个实例中使用：
    // 创建根实例
    new Vue({
        el: '#appCommand02',
        directives: {
            // 注册一个局部的自定义指令 v-focus
            focus: {
                // 指令的定义
                inserted: function (el) {
                    // 聚焦元素
                    el.focus()
                }
            }
        }
    })
</script>

<!--
    /*
    钩子
        钩子函数
        指令定义函数提供了几个钩子函数（可选）：

    bind: 只调用一次，指令第一次绑定到元素时调用，用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

    inserted: 被绑定元素插入父节点时调用（父节点存在即可调用，不必存在于 document 中）。

    update: 被绑定元素所在的模板更新时调用，而不论绑定值是否变化。通过比较更新前后的绑定值，可以忽略不必要的模板更新（详细的钩子函数参数见下）。

    componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。

    unbind: 只调用一次， 指令与元素解绑时调用。

    钩子函数参数
        钩子函数的参数有：

    el: 指令所绑定的元素，可以用来直接操作 DOM 。
    binding: 一个对象，包含以下属性：
    name: 指令名，不包括 v- 前缀。
    value: 指令的绑定值， 例如： v-my-directive="1 + 1", value 的值是 2。
    oldValue: 指令绑定的前一个值，仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    expression: 绑定值的表达式或变量名。 例如 v-my-directive="1 + 1" ， expression 的值是 "1 + 1"。
    arg: 传给指令的参数。例如 v-my-directive:foo， arg 的值是 "foo"。
    modifiers: 一个包含修饰符的对象。 例如： v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
    vnode: Vue 编译生成的虚拟节点。
    oldVnode: 上一个虚拟节点，仅在 update 和 componentUpdated 钩子中可用。
    */-->
<!--    // demo01-->
<div id="appHook"  v-runoob:hello.a.b="message">
</div>
<script>
        Vue.directive('runoob', {
        bind: function (el, binding, vnode) {
        var s = JSON.stringify
        el.innerHTML =
        'name: '       + s(binding.name) + '<br>' +
        'value: '      + s(binding.value) + '<br>' +
        'expression: ' + s(binding.expression) + '<br>' +
        'argument: '   + s(binding.arg) + '<br>' +
        'modifiers: '  + s(binding.modifiers) + '<br>' +
        'vnode keys: ' + Object.keys(vnode).join(', ')
    }
    })
        new Vue({
        el: '#app',
        data: {
        message: '菜鸟教程!'
    }
    })
</script>
<!--demo02-->
<div id="appHook02">
    <div v-runoob="{ color: 'green', text: '菜鸟教程!' }"></div>
</div>

<script>
    Vue.directive('runoob', function (el, binding) {
        // 简写方式设置文本及背景颜色
        el.innerHTML = binding.value.text
        el.style.backgroundColor = binding.value.color
    })
    new Vue({
        el: '#appHook02'
    })
</script>
</body>
</html>